package GSEA::Pvalue::PvalueCalculator;

use strict ;
use warnings;
use Math::Bigfloat;
use Math::Counting;

use GSEA::Pvalue::Map ;
use GSEA::Pvalue::Chrono ;

sub constrPvalueCalculator($ $ $ $)  
{
	my ($classe , $Nhit ,  $Nmiss , $score ) = @_; 
	
	
	if( ! defined($Nhit) 	){ die("argument 'Nhit' is not set , error");}
	if( ! defined($Nmiss) 	){ die("argument 'Nmiss' is not set , error");}
	if( ! defined($score)	){ die("argument 'score' is not set , error");}

	
	my $this = {
					"Nhit"		=> $Nhit	,
					"Nmiss"		=> $Nmiss	,					
					"score"		=> abs($score)	
				};
	
	bless ($this,$classe);  
		
	return $this;  
}



sub compute($)
{
	( my $this ) = @_ ; 
	
	my $width	= $this->{"Nhit"}	;
	my $height	= $this->{"Nmiss"}	;
	my $score	= $this->{"score"}	;
	
	if( $score==0 	){ return 0.5 ; }
	if( abs($score)==1 	){ return 0 ; }
	
	my $TotalChrono = GSEA::Pvalue::Chrono->constrChrono();
	
 	
	# calculate the total number of posssible ways ,using combinations.
	my $result2 = Math::BigFloat->new( (Math::Counting::bcomb($width + $height ,$height)  ) );
	

	# calculate the number of ways which are lower than our score .  
	# then we do asubstraction for having the number of ways that are better than our score.
	my $map = GSEA::Pvalue::Map->constrMap( $width , $height , $score ) ; 
	my $result1 = Math::BigFloat->new( $map->getWays() );
	
	
	#print("\ncomb=$result2");
	#print("\nways=$result1");
	
	
	#my $tmp = Math::BigFloat->new( $result1 / $result2 );
	#print("\n way /comb =$tmp");
	
	
	
	# calculate the ratio = pvalue.
	$result1 = $result2 - $result1 ;
	#print("\ncomb - way = $result1");
	
	my $result = Math::BigFloat->new( ( $result1 / $result2 ) / 2 );
	#print("\n(comb - way)/comb /2=$result");
	
	
	return $result ;
}

1;
